
/*
 * Java class "AntiGravCTargeting.java" generated from Poseidon for UML.
 * Poseidon for UML is developed by <A HREF="http://www.gentleware.com">Gentleware</A>.
 * Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
 */
package jcs;



/**
 * 
 * @poseidon-object-id [sm$79a4c9:ffff7b5b94:-7ff0]
 */
public class AntiGravCTargeting extends TargetingMode {

  ///////////////////////////////////////
  // attributes


/**
 * <p>Represents ...</p>
 * @poseidon-object-id [sm$31b810:ffff82645c:-7f81]
 */
    private double xWall; 

/**
 * <p>Represents ...</p>
 * @poseidon-object-id [sm$31b810:ffff82645c:-7f82]
 */
    private double yWall; 

/**
 * <p>Represents ...</p>
 * @poseidon-object-id [sm$31b810:ffff82645c:-7f8c]
 */
    private double WALL_TOLERANCE = 100.0; 

  ///////////////////////////////////////
  // operations


/**
 * <p>Does ...</p>
 * 
 * 
 * @poseidon-object-id [sm$79a4c9:ffff7b5b94:-7ff6]
 * @return 
 * @param target 
 */
    public double calcBulletPower(Enemy target) {        
        double distance = seth.getCurrentPos().calcDist(target.getCoord());  
        double power = 3.0;
                      /*  double scalar = 0.90;
                        if(distance > POWER_BUFFER)
                        {
                        	scalar = POWER_BUFFER / distance;
                        }
                        else
                        {
                        	scalar = 0.0;	
                        }
                        double power = 3.0 * (1.0 - scalar);
                        return power;
         **/
        
        if(distance < POWER_BUFFER)
        {
            power = 3.0;
        }
        else
        {
            double temp = distance - POWER_BUFFER + 1;
            power = 3.0 * POWER_BUFFER * (target.getRatio(0) / distance);
        }
        
        if(seth.getEnergy() < 9.1 && power > seth.getEnergy())
        {
            power = seth.getEnergy() / 3.0;
        }
        if( power * 4.0 > target.getEnergy())
        {
            power = target.getEnergy() / 4.0;
        }
        return power;
    } // end calcBulletPower        

/**
 * <p>Does ...</p>
 * 
 * 
 * @poseidon-object-id [sm$79a4c9:ffff7b5b94:-7ff5]
 * @return 
 * @param target 
 * @param time 
 */
    public double calcPoint(Enemy target, double time) {        
                
        		// antigrav seems quite popular, we should be able to hit it pretty well
                // calc walls plus centre
                Coord walls,centre, bots, temp, AGFire, enemyVector;
                Enemy[] enemies = seth.getEnemyList().getEnemies();
                double botX =  0.0;
                double botY =  0.0;
                double xSum =  0.0;
                double ySum =  0.0;
                double distance = time * target.getVelocity();
                walls = wallSum(target.getCoord());
                centre = pointSum( target.getCoord(), new Coord(xWall/ 2.0, yWall/ 2.0),  0.5 );
                // calc other bots (inclucing seth!)
        		for(int i = 0; i< enemies.length && enemies[i] != null; i++)
                {
                	if(enemies[i] == target)
                	{	// from target to target is silly, try from target to seth
                		temp = pointSum(target.getCoord(),seth.getCurrentPos(), 1);
                	}
                	else
                	{   // from target to other enemies
                    	temp = pointSum(target.getCoord(), enemies[i].getCoord(), 1);
                    }
                    botX += temp.getX();
                    botY += temp.getY();
                } 
                if(target.getCoord().calcDist(centre) > 2)
                {
               		xSum = botX / (seth.getEnemyList().getCount() + 1) + walls.getX() + centre.getX();
               		ySum = botY / (seth.getEnemyList().getCount() + 1)+ walls.getY() + centre.getY();
               	}
               	else
               	{
               		xSum = botX / (seth.getEnemyList().getCount() + 1) + walls.getX();
               		ySum = botY / (seth.getEnemyList().getCount() + 1)+ walls.getY();
               	}
               	enemyVector = target.getCoord().getCoordFromScan(target.getBearing(), distance/ DISTANCE_FACTOR);
               	AGFire = new Coord(xSum + enemyVector.getX(),ySum + enemyVector.getY());
               	System.out.println("firing by antigrav C at : " + AGFire.toString());
                return seth.getCurrentPos().calcHeading( AGFire );
    } // end calcPoint        

/**
 * lock-end
 * 
 * @poseidon-object-id [sm$79a4c9:ffff7b5b94:-7ff4]
 * @return 
 * @param currentPos 
 */
    private Coord wallSum(Coord currentPos) {        
        
         	double sumX =   0.0;
        	double sumY =   0.0;
        	if( currentPos.getX() < WALL_TOLERANCE)
        	{
        		sumX += WALL_FACTOR * (1 / currentPos.getX());
        	}
        	if( currentPos.getY() < WALL_TOLERANCE)
        	{
        		sumY += WALL_FACTOR * (1 / currentPos.getY());
        	}
        	if( xWall - currentPos.getX() < WALL_TOLERANCE)
        	{
        		sumX -= WALL_FACTOR * (1 / (xWall - currentPos.getX()));
        	}
        	if( yWall - currentPos.getY() < WALL_TOLERANCE)
        	{
        		sumY -= WALL_FACTOR * (1 / (yWall - currentPos.getY()));
        	}		
        return new Coord(sumX, sumY);
    } // end wallSum        

/**
 * 
 * 
 * @poseidon-object-id [sm$79a4c9:ffff7b5b94:-7ff3]
 * @return 
 * @param currentPos 
 * @param enemyPos 
 * @param power 
 */
    private Coord pointSum(Coord currentPos, Coord enemyPos, double power) {        
         
        	double distance = currentPos.calcDist(enemyPos);
          double theta = enemyPos.calcHeading(currentPos);
          double force = power * BOT_FACTOR * (1 / distance);
          Coord sum = currentPos.getCoordFromScan( theta, force );			
          sum.setX( sum.getX() - currentPos.getX() );
          sum.setY( sum.getY() - currentPos.getY() );
          return sum;
    } // end pointSum        

/**
 * <p>Does ...</p>
 * 
 * @poseidon-object-id [sm$31b810:ffff82645c:-7fa3]
 * @param _seth 
 */
    public  AntiGravCTargeting(Seth _seth) {        
        seth = _seth;
        	xWall = _seth.getBattleFieldWidth();
        		yWall = _seth.getBattleFieldHeight();
    } // end AntiGravCTargeting        

 } // end AntiGravCTargeting


